package cn.sunxyz.methodinference.parser;

import cn.sunxyz.methodinference.rule.SQLKeywords;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by yangrd on 2017/5/31.
 */
public class DefaultSQLParser extends AbstractSQLParser {


    private Map<SQLKeywords.Keywords, String> sqlDialect = new HashMap<>();

    {
        registerDialect(SQLKeywords.Keywords.AND, " AND ");
        registerDialect(SQLKeywords.Keywords.OR, " OR ");
        registerDialect(SQLKeywords.Keywords.BETWEEN, " BETWEEN ? AND ?");
        registerDialect(SQLKeywords.Keywords.LESS_THAN, " < ?");
        registerDialect(SQLKeywords.Keywords.LESS_THAN_EQUAL, " <= ?");
        registerDialect(SQLKeywords.Keywords.GREATER_THAN, " > ?");
        registerDialect(SQLKeywords.Keywords.GREATER_THAN_EQUAL, " >= ?");
        registerDialect(SQLKeywords.Keywords.IS_NULL, " IS NULL");
        registerDialect(SQLKeywords.Keywords.NOT_NULL, " NOT NULL");
        registerDialect(SQLKeywords.Keywords.IS_NOT_NULL, " NOT NULL");
        registerDialect(SQLKeywords.Keywords.LIKE, " LIKE ?");
        registerDialect(SQLKeywords.Keywords.NOT_LIKE, " NOT LIKE ?");
        registerDialect(SQLKeywords.Keywords.NOT, "  <> ?");
        registerDialect(SQLKeywords.Keywords.IN, " IN (:?)");//需要后期根据Array 或 collection 长度设置 ?个数
        registerDialect(SQLKeywords.Keywords.NOT_IN, " NOT IN (:?)");
        registerDialect(SQLKeywords.Keywords.ORDER_BY, " ORDER BY ");
        registerDialect(SQLKeywords.Keywords.DESC, " DESC");
        registerDialect(SQLKeywords.Keywords.ASC, " ASC");
    }


    @Override
    public String parser(List<Object> extractList) {
        StringBuilder sb = new StringBuilder();
        int len = extractList.size();
        Boolean flag = false;
        for (int i = 0; i < len; i++) {
            Object o = extractList.get(i);
            if (o instanceof String) { //属性
                if (flag) {
                    sb.append(getProperty(o.toString()));
                } else {
                    sb.append(getProperty(o.toString()) + ":w");
                }
            } else if (o instanceof SQLKeywords.Keywords) {//sql关键字
                SQLKeywords.Keywords keywords = (SQLKeywords.Keywords) o;
                SQLKeywords.KeywordsPosition position = keywords.getPosition();
                switch (position) {
                    case LEFT:
                        if (keywords.equals(SQLKeywords.Keywords.ORDER_BY) && i == len - 2) {//没有desc 或 asc后缀
                            flag = true;
                        }
                    case MIDDLE:
                        sb.append(getDialect(keywords));
                        break;
                    case RIGHT:
                        int index = sb.lastIndexOf(":w");
                        sb.replace(index, index + 2, getDialect(keywords));
                        break;
                }
            }
        }
        //将没有属性条件的当做=处理
        while (sb.indexOf(":w") > 0) {
            int index = sb.indexOf(":w");
            sb.replace(index, index + 2, " = ?");
        }
        return sb.toString();
    }

    //用于获取类中属性对应的关键字
    public String getProperty(String prop) {
        return prop;
    }

    protected void registerDialect(SQLKeywords.Keywords keywords, String sql) {
        sqlDialect.put(keywords, sql);
    }

    protected String getDialect(SQLKeywords.Keywords keywords) {
        return sqlDialect.get(keywords);
    }
}
